#pragma once

#include "PyDll.h"

HMODULE pydll;
wVoid Py_GetPath;
//cWsize Py_EncodeLocale = (cWsize)GetProcAddress(pydll, "Py_EncodeLocale");
oofun PyObject_Repr;
oofun PyObject_Type;
iofun PyLong_Check;
pPyLong_AsLong PyLong_AsLong;
iofun PyFloat_Check;
pPyFloat_AsDouble PyFloat_AsDouble;
iofun PyBytes_Check;
iofun PyObject_Size;
iofun PyBytes_Size;
pPyBytes_AsString PyBytes_AsString;
pPyBytes_AsString PyByteArray_AsString;
iofun _PyUnicode_CheckConsistency;
ooc PyObject_GetAttrString;
ioco PyObject_SetAttrString;
pPy_GetVersion Py_GetVersion;
wVoid Py_GetPythonHome;

pPy_DecodeLocale Py_DecodeLocale;
pPy_SetPath Py_SetPath;
ovoid PyErr_Occurred;

voidp PyMem_Free;
voidvoid Py_Initialize;
ivoid Py_IsInitialized;
wVoid Py_GetProgramFullPath;
wVoid Py_GetExecPrefix;
voidvoid Py_FinalizeEx;
pcfun PyImport_ImportModule;
oofun PyImport_Import;
ooc PyUnicode_EncodeLocale;

voidO Py_IncRef;
voidO Py_DecRef;
pPyModule_AddFunctions PyModule_AddFunctions;
pPy_VaBuildValue Py_VaBuildValue;
oooFun PyObject_CallObject;
oofun PyObject_CallFunctionObjArgs;

icc PyRun_SimpleString;
pPyArg_VaParse PyArg_VaParse;
woifun PyUnicode_AsWideCharString;
ovoid PyEval_GetBuiltins;
ovoid PyEval_GetLocals;
ovoid PyEval_GetGlobals;
// Pyobj
oooFun PyObject_GetItem;
iooofun PyObject_SetItem;
oooo PyObject_Call;
oooFun PyObject_GetAttr;
iooofun PyObject_SetAttr;
iofun PyCallable_Check;

//PyTuple
oint PyTuple_New;
ooi PyTuple_GetItem;
ioiofun PyTuple_SetItem;
ooii PyTuple_GetSlice;

//list
oint PyList_New;
ioiofun PyList_Insert;
ioofun PyList_Append;
oofun PyList_AsTuple;
ooi PyList_GetItem;
ioiofun PyList_SetItem;
ooii PyList_GetSlice;


//dict
ovoid PyDict_New;
voidO PyDict_Clear;
ioofun PyDict_Contains;
oofun PyDict_Copy;
oofun PyDict_Keys;
oofun PyDict_Values;
oooFun PyDict_GetItem;
iooofun PyDict_SetItem;
pPyDict_Next PyDict_Next;
oofun PyModule_GetDict;
oofun PyModule_GetNameObject;
pcfun PyBytes_FromString;
oint PyLong_FromLong;
oint PyBool_FromLong;
occ PyUnicode_DecodeLocale;
oci PyByteArray_FromStringAndSize;
od PyFloat_FromDouble;
oofun PyImport_GetModule;
ioco PyModule_AddObject;
ovoid PyImport_GetModuleDict;
voidOOOPtr PyErr_Fetch;
voidOOO PyErr_Restore;
ivoid PyGILState_Ensure;
voidi PyGILState_Release;
voidvoid PyEval_InitThreads;
ivoid PyGILState_Check;
ivoid PyThreadState_Get;
ivoid PyEval_SaveThread;
voidi PyEval_RestoreThread;
iifun PyThreadState_Swap;
oofun PyObject_GetIter;
oofun PyIter_Next;

iocx PyArg_ParseTuple;



bool  SetDllPath(char* pstr) {
	pydll = LoadLibrary(pstr);
	if (pydll == NULL)
	{
		return false;
	}
	Py_GetPath = (wVoid)GetProcAddress(pydll, "Py_GetPath");
	PyObject_Repr = (oofun)GetProcAddress(pydll, "PyObject_Repr");
	PyObject_Type = (oofun)GetProcAddress(pydll, "PyObject_Type");
	PyLong_Check = (iofun)GetProcAddress(pydll, "PyLong_Check");
	PyLong_AsLong = (pPyLong_AsLong)GetProcAddress(pydll, "PyLong_AsLong");
	PyFloat_Check = (iofun)GetProcAddress(pydll, "PyFloat_Check");
	PyFloat_AsDouble = (pPyFloat_AsDouble)GetProcAddress(pydll, "PyFloat_AsDouble");
	PyBytes_Check = (iofun)GetProcAddress(pydll, "PyBytes_Check");
	PyObject_Size = (iofun)GetProcAddress(pydll, "PyObject_Size");
	PyBytes_Size = (iofun)GetProcAddress(pydll, "PyBytes_Size");
	PyErr_Occurred = (ovoid)GetProcAddress(pydll, "PyErr_Occurred");
	Py_DecodeLocale = (pPy_DecodeLocale)GetProcAddress(pydll, "Py_DecodeLocale");
	PyBytes_AsString = (pPyBytes_AsString)GetProcAddress(pydll, "PyBytes_AsString");
	PyByteArray_AsString = (pPyBytes_AsString)GetProcAddress(pydll, "PyByteArray_AsString");

	_PyUnicode_CheckConsistency = (iofun)GetProcAddress(pydll, "_PyUnicode_CheckConsistency");
	PyObject_GetAttrString = (ooc)GetProcAddress(pydll, "PyObject_GetAttrString");
	PyObject_SetAttrString = (ioco)GetProcAddress(pydll, "PyObject_SetAttrString");
	Py_GetVersion = (pPy_GetVersion)GetProcAddress(pydll, "Py_GetVersion");
	Py_GetPythonHome = (wVoid)GetProcAddress(pydll, "Py_GetPythonHome");

	Py_SetPath = (pPy_SetPath)GetProcAddress(pydll, "Py_SetPath");
	PyMem_Free = (voidp)GetProcAddress(pydll, "PyMem_Free");
	Py_Initialize = (voidvoid)GetProcAddress(pydll, "Py_Initialize");
	Py_IsInitialized = (ivoid)GetProcAddress(pydll, "Py_IsInitialized");
	Py_GetProgramFullPath = (wVoid)GetProcAddress(pydll, "Py_GetProgramFullPath");
	Py_GetExecPrefix = (wVoid)GetProcAddress(pydll, "Py_GetExecPrefix");
	Py_FinalizeEx = (voidvoid)GetProcAddress(pydll, "Py_FinalizeEx");
	PyImport_ImportModule = (pcfun)GetProcAddress(pydll, "PyImport_ImportModule");
	PyImport_Import = (oofun)GetProcAddress(pydll, "PyImport_Import");

	PyUnicode_EncodeLocale = (ooc)GetProcAddress(pydll, "PyUnicode_EncodeLocale");

	Py_IncRef = (voidO)GetProcAddress(pydll, "Py_IncRef");
	Py_DecRef = (voidO)GetProcAddress(pydll, "Py_DecRef");
	PyModule_AddFunctions = (pPyModule_AddFunctions)GetProcAddress(pydll, "PyModule_AddFunctions");
	Py_VaBuildValue = (pPy_VaBuildValue)GetProcAddress(pydll, "Py_VaBuildValue");
	PyObject_CallObject = (oooFun)GetProcAddress(pydll, "PyObject_CallObject");
	PyObject_CallFunctionObjArgs = (oofun)GetProcAddress(pydll, "PyObject_CallFunctionObjArgs");

	PyRun_SimpleString = (icc)GetProcAddress(pydll, "PyRun_SimpleString");
	PyArg_VaParse = (pPyArg_VaParse)GetProcAddress(pydll, "PyArg_VaParse");
	PyUnicode_AsWideCharString = (woifun)GetProcAddress(pydll, "PyUnicode_AsWideCharString");
	PyEval_GetBuiltins = (ovoid)GetProcAddress(pydll, "PyEval_GetBuiltins");
	PyEval_GetLocals = (ovoid)GetProcAddress(pydll, "PyEval_GetLocals");
	PyEval_GetGlobals = (ovoid)GetProcAddress(pydll, "PyEval_GetGlobals");
	// Pyobj
	PyObject_GetItem = (oooFun)GetProcAddress(pydll, "PyObject_GetItem");
	PyObject_SetItem = (iooofun)GetProcAddress(pydll, "PyObject_SetItem");
	PyObject_Call = (oooo)GetProcAddress(pydll, "PyObject_Call");
	PyObject_GetAttr = (oooFun)GetProcAddress(pydll, "PyObject_GetAttr");
	PyObject_SetAttr = (iooofun)GetProcAddress(pydll, "PyObject_SetAttr");
	PyCallable_Check = (iofun)GetProcAddress(pydll, "PyCallable_Check");

	//PyTuple
	PyTuple_New = (oint)GetProcAddress(pydll, "PyTuple_New");
	PyTuple_GetItem = (ooi)GetProcAddress(pydll, "PyTuple_GetItem");
	PyTuple_SetItem = (ioiofun)GetProcAddress(pydll, "PyTuple_SetItem");

	//list
	PyList_New = (oint)GetProcAddress(pydll, "PyList_New");
	PyList_Insert = (ioiofun)GetProcAddress(pydll, "PyList_Insert");
	PyList_Append = (ioofun)GetProcAddress(pydll, "PyList_Append");
	PyList_AsTuple = (oofun)GetProcAddress(pydll, "PyList_AsTuple");
	PyList_GetItem = (ooi)GetProcAddress(pydll, "PyList_GetItem");
	PyList_SetItem = (ioiofun)GetProcAddress(pydll, "PyList_SetItem");
	PyList_GetSlice = (ooii)GetProcAddress(pydll, "PyList_GetSlice");

	//dict
	PyDict_New = (ovoid)GetProcAddress(pydll, "PyDict_New");
	PyDict_Clear = (voidO)GetProcAddress(pydll, "PyDict_Clear");
	PyDict_Contains = (ioofun)GetProcAddress(pydll, "PyDict_Contains");
	PyDict_Copy = (oofun)GetProcAddress(pydll, "PyDict_Copy");
	PyDict_Keys = (oofun)GetProcAddress(pydll, "PyDict_Keys");
	PyDict_Values = (oofun)GetProcAddress(pydll, "PyDict_Values");
	PyDict_GetItem = (oooFun)GetProcAddress(pydll, "PyDict_GetItem");
	PyDict_SetItem = (iooofun)GetProcAddress(pydll, "PyDict_SetItem");
	PyDict_Next = (pPyDict_Next)GetProcAddress(pydll, "PyDict_Next");

	PyModule_GetDict = (oofun)GetProcAddress(pydll, "PyModule_GetDict");
	PyModule_GetNameObject = (oofun)GetProcAddress(pydll, "PyModule_GetNameObject");
	PyImport_GetModule = (oofun)GetProcAddress(pydll, "PyImport_GetModule");


	PyBytes_FromString = (pcfun)GetProcAddress(pydll, "PyBytes_FromString");
	PyLong_FromLong = (oint)GetProcAddress(pydll, "PyLong_FromLong");
	PyBool_FromLong = (oint)GetProcAddress(pydll, "PyBool_FromLong");
	PyUnicode_DecodeLocale = (occ)GetProcAddress(pydll, "PyUnicode_DecodeLocale");
	PyByteArray_FromStringAndSize = (oci)GetProcAddress(pydll, "PyByteArray_FromStringAndSize");
	PyFloat_FromDouble = (od)GetProcAddress(pydll, "PyFloat_FromDouble");
	PyTuple_GetSlice = (ooii)GetProcAddress(pydll, "PyTuple_GetSlice");
	PyModule_AddObject = (ioco)GetProcAddress(pydll, "PyModule_AddObject");
	PyImport_GetModuleDict = (ovoid)GetProcAddress(pydll, "PyImport_GetModuleDict");
	PyErr_Fetch = (voidOOOPtr)GetProcAddress(pydll, "PyErr_Fetch");
	PyErr_Restore = (voidOOO)GetProcAddress(pydll, "PyErr_Restore");
	PyGILState_Ensure = (ivoid)GetProcAddress(pydll, "PyGILState_Ensure");
	PyGILState_Release = (voidi)GetProcAddress(pydll, "PyGILState_Release");
	PyEval_InitThreads = (voidvoid)GetProcAddress(pydll, "PyEval_InitThreads");
	PyGILState_Check = (ivoid)GetProcAddress(pydll, "PyGILState_Check");
	PyThreadState_Get = (ivoid)GetProcAddress(pydll, "PyThreadState_Get");
	PyEval_SaveThread = (ivoid)GetProcAddress(pydll, "PyEval_SaveThread");
	PyEval_RestoreThread = (voidi)GetProcAddress(pydll, "PyEval_RestoreThread");
	PyThreadState_Swap = (iifun)GetProcAddress(pydll, "PyEval_RestoreThread");
	PyObject_GetIter = (oofun)GetProcAddress(pydll, "PyObject_GetIter");
	PyIter_Next = (oofun)GetProcAddress(pydll, "PyIter_Next");
	PyArg_ParseTuple = (iocx)GetProcAddress(pydll, "PyArg_ParseTuple");


	return true;
}
